home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-01-18 | 86.2 KB | 1,802 lines |
-
- PASCAL MAGIC
-
- (c) Copyright 1992, Jeff Napier & Another Company
-
-
- Tutorial File
-
-
- What Pascal Magic can do for you:
-
- This disk consists of three parts, Magic.Tpu, Magic.Doc
- and Tutorial.Txt. Magic.Tpu is an add-in for Borland's Turbo
- Pascal version 6.0 which will make your job as a programmer
- much easier and your results much more polished. Magic.Doc is
- a text file which explains how to use all the features of
- Magic.Tpu, and Magic.Tut, the file you are now reading, is a
- tutorial which starts at a very beginning level and quickly,
- but effortlessly moves into advanced programming techniques.
-
- Specifically, Magic.Tpu offers the following:
-
- * Automatic pop-up text boxes, dialog boxes and light-bar
- menus.
-
- * Automatic handling of text files.
-
- * Built-in mouse support for the programs you create.
-
- * Support for graphics programs to make them as easy to write
- as text-based programs.
-
- * Incorporation of .BGI and .CHR files directly into finished
- .EXE files.
-
- * Sound effects for your programs.
-
- * Simplification of many Turbo Pascal operations.
-
- * Complete color control in text and graphics modes.
-
- * Build cursor control into your programs for laptop LCD
- screens.
-
- * Full, documented, easy-to-understand source code is
- available so you can learn from and customize the Magic
- framework to your own applications.
-
- NOTE:
-
- This is a shareware product. You have our specific
- permission to copy and distribute this package as long as all
- files remain intact and unchanged.
- If you benefit from this tutorial, or if you use the
- Magic.Tpu unit in your programs you are expected to register.
- To register, send $29.95 to:
-
- Another Company
- P.O. Box 298
- Applegate, OR 97530
- USA
-
- If you would like the full source code with your
- registration, send $59.90. Please specify disk size.
-
- QUESTIONS:
-
- If you have questions: 503-846-7884, 9-5 Weekdays, West Coast
- time. (We are not always available during those hours.)
-
- THE BEST WAY TO USE THIS TUTORIAL:
-
- Copy Magic.Tpu to the directory where you keep your Pascal
- *.tpu files, and copy Tutorial.txt to the directory which
- contains your *.pas files. Start your Turbo.Exe and load in
- this file, (type: TURBO TUTORIAL.TXT). Since the Turbo Pascal
- IDE (Integrated Development Environment) allows you to work
- on several files at once, you can read this tutorial in one
- window and work on practice programs in another window. If
- you don't know how yet, I'll show you. If you are an
- experienced programmer, you might want to skip through this
- tutorial and concentrate only on the areas that are new to
- you.
-
- A COUPLE OF OTHER NOTES:
-
- 1. It is assumed that you have legally purchased Turbo Pascal
- version 6.0 and therefore have the four valuable printed
- manuals that come with the program. If not, you are advised
- to go spend a little money and get what you need, because
- there are places within this tutorial which will refer you to
- those books to complete your knowledge.
-
- 2. This is not the last word on Turbo Pascal. It doesn't
- teach everything about programming - probably not even 10
- percent of what you will eventually learn, but between this
- tutorial and the Borland manuals, you'll get pretty good at
- programming, and fairly quickly. One of the best ways to
- learn this is to experiment frequently. Tear the example
- programs apart and try to interject your own ideas into them.
- See what you can change or improve, then run the programs you
- have modified and see what happens. As you well know, you
- can't hurt your computer by typing an incorrect line of code.
-
- 3. Turbo Pascal is not sensitive to capitalization or white
- space. The exact placement of indentations is not important
- and every programmer develops a slightly different style. In
- this tutorial, I have tried to capitalize letters within
- procedure and function names where such capitalization may
- make the source code easier to read. This 'convention' occurs
- irregularly throughout this tutorial.
-
- 4. This is version 1.0 of what I believe is a wonderful
- product, but then, I wrote it. Let me know what you think.
- I'm pretty sure I caught all the major bugs, but there may be
- some minor ones. Most likely the registered and/or subsequent
- shareware versions will be even better!
-
- 5. To use Magic.tpu, Video.tpu and Fonts.tpu will also need
- to be available in the same sub-directory. Also, Graph.tpu,
- furnished with Turbo Pascal must be in the sub-directory.
-
-
- HERE WE GO:
-
- Here is the simplest program you can write:
-
- begin
- end.
-
- Let's try it out. Press [F3]. (First finish reading this
- paragraph so you know how to get back.) A window pops up
- asking for a file name. Call it Prog1 (or any name you
- choose) and type the preceding two-line program. Don't
- forget the period after end. In Pascal, there is no need to
- care about capitalization, Capitals, small case or mixed-case
- makes no difference. Press [F2] to save your valuable work
- against power failure, etc. While holding the [Ctrl] key,
- press [F9] and the program will run. Did you blink? Since,
- the program doesn't actually do anything, it runs very
- quickly, then returns to Turbo Pascal. To switch back to the
- first window, press [Alt] and [1].
-
- This next program is just like the first, it doesn't do
- anything, but it is also a legal program. There is one more
- line starting with the word Program. Some versions of Pascal
- require this line, but with Turbo Pascal, it is optional.
-
- program prog2;
- begin
- end.
-
- Next, we'll add something to the program so it will actually
- have a purpose:
-
- program prog3;
- begin
- write('Hello, World!');
- end.
-
- This program only does one thing, it "write"s the text
- between the single quote marks to the screen. Turbo Pascal,
- like all computer applications is sensitive to exact spelling
- and punctuation. Make sure you have a colon at the end of the
- write('Hello, World!'); line, and that all the other pieces
- are in their proper places.
- Go ahead and run this program. Press [Alt] and [2] to
- get back to the other window you opened, and add the lines to
- make the first program into this one. Or, if you wish, you
- can make a block around this prog3, using the mouse or with
- ^KB the arrow keys ^KK, (actually there are several ways to
- mark a block). Then press [Alt] and [E], then [C]. This puts
- a copy of the marked block in the Turbo Pascal clipboard.
- Switch to the other window (use [Alt]-[2], or [Alt]- [W],
- [L]). Then press [Alt]-[E], then [P] to paste the block into
- the second window. Erase the previous program, then compile
- and run the new prog3.
- It happened very quickly, didn't it? Lets slow it down in
- prog4:
-
- program prog4;
- begin
- write('Hello, World!');
- readln;
- end.
-
- In prog4, the line readln causes the computer to wait for the
- user to press the [Enter] key. Now you can take time to
- contemplate your "Hello, World!" line.
- You may notice that the screen wasn't cleared of other
- junk when prog4 ran. In prog5, let's clear the screen, giving
- the "Hello, World!" line more clarity. We'll use the
- procedure clrscr, which Turbo Pascal provides to clear the
- screen.
-
- program prog5;
- begin
- clrscr;
- write('Hello, World!');
- readln;
- end.
-
- What happened? If you tried to run this program, you'll have
- noticed that it didn't work. Turbo Pascal does not recognize
- "clrscr." Did I misspell it? No. I didn't tell you that
- clrscr is not part of Turbo Pascal itself. It is in a library
- of operations for screen handling called Crt.
- Turbo Pascal provides 5 special libraries of routines,
- called units. They are Crt, System, Printer, Printer, and
- Dos. You can also create your own custom units, or buy
- special units from programmers.
- These 5 are special because they are grouped together in a
- special file called Turbo.Tpl, but usually units are separate
- files with the extension of .Tpu. The corrected prog5a shows
- how to use a unit:
-
- program prog5a;
- uses crt;
- begin
- clrscr;
- write('Hello, World!');
- readln;
- end.
-
- As the proper prog5 indicates, to use something within a
- unit, simply declare the unit's name in the "uses" line,
- which you must type just below the "program" line, or as the
- first line in the program.
-
- Let's get a bit fancier, take a look at prog6.
-
- program prog6;
- uses crt,magic;
- begin
- sent[1] := 'Hello, World!';
- GetAnyKey(5,11);
- end.
-
- Prog6 uses the Magic.Tpu unit. Give this program a try. Kind
- of prettier, isn't it? Let's talk about prog6 in detail.
- You'll notice that instead of writing "Hello, World!"
- directly to the screen, we have assigned that string of
- characters to a variable called "sent[1]." In the magic unit,
- "sent" is an array of sentences called strings. An array is a
- group of something, all of which are the same type and size.
- The "sent" array is 46 strings, each of which can contain up
- to 76 characters. In prog6, we have used only one of them,
- the first one, number [1]. When you want to specify a certain
- item from an array of items, you put its number in square
- brackets. Until sent[1] was told to equal with ":=" (called
- "assignment equals") "Hello, World!," it was nothing. Until
- prog6 assigned "Hello, World!" to it, sent[1] was equal to
- nothing, like this: sent[1] := ''. In fact, all the other
- sent[]s in prog6 are still nothing. The magic unit will use
- only the sent[]s which contain data.
- The next line, "GetAnyKey(5,11)" calls a procedure that
- displays the sent[]s which contain data in a bordered,
- shadowed box, and waits for the user to press any key or
- click a mouse button. The two numbers following GetAnyKey are
- coordinates. These refer to the position on the screen where
- the box is to pop up. Specifically, they mark the upper left
- corner of the pop-up box.
- The first number is the horizontal position on the screen.
- If it were 1, then the box would be jammed up against the
- left hand edge of the screen. 80 is the right-hand edge of a
- standard text screen since it is 80 characters wide, but you
- can't put the left edge of a text box there if you want to
- see it.
- The second number is, of course, the vertical coordinate,
- with 1 being the top of the screen and 25 being the bottom.
- You'll notice, that clrscr is missing. It is not needed
- with the magic unit, since the unit automatically clears the
- screen when the program starts. But, I left "Crt" in the uses
- statement. This is easy programming practice, because if you
- don't use anything from the Crt unit, Turbo Pascal does not
- increase the size of the compiled program. Yet, if you need
- something from the unit, it is at your disposal. You'll see
- that many of my programs "use" the Crt unit, even though they
- don't end up using anything in the Crt unit.
-
- Prog7 illustrates a close relative to GetAnyKey, GetYN. While
- GetAnyKey waits for the user to press almost anything, GetYN
- stalls the program until the user presses [Y] or [N], or
- clicks the left or right mouse button. Also, you'll note that
- one of the coordinates is a negative number. In the
- preceding paragraphs, you'll notice I didn't allow for the
- possibility of a negative screen coordinate, and technically
- there is no such thing. When the magic unit comes across a
- negative coordinate, it ignores the number and automatically
- figures out where the center of the screen is and pops up its
- box there! In other words, if you pass a negative number for
- the vertical location, the box will be between the top and
- bottom of the screen. If you use a negative number for the
- horzontal location, the box will be centered right to left on
- the screen.
-
- program prog7;
- uses crt, magic;
- begin
- sent[1] := 'Do you want to quit? (Y/N)';
- sent[2] := '';
- sent[3] := 'This is just a test, actually, the program';
- sent[4] := 'is gonna quit whether you answer Y or N';
- GetYN(-5,3);
- end.
-
- Let's make a slight improvement in the next program. Prog8
- changes a boolean variable, declared from the magic unit. A
- boolean is a variable which can have only two values, true or
- false. This particular variable is CenterJustify. Normally,
- it is false (the "default" condition) but if changed to true,
- then the strings in the sent array will be centered within
- any pop-up box. Run prog8 and you'll see what I mean.
-
- program prog8;
- uses crt, magic;
- begin
- sent[1] := 'Do you want to quit? (Y/N)';
- sent[2] := '';
- sent[3] := 'This is just a test, actually, the program';
- sent[4] := 'is gonna quit whether you answer Y or N';
- CenterJustify := true;
- GetYN(-5,3);
- end.
-
- Prog8 is a little prettier, n'est ce pas? Prog9 will walk its
- talk, it won't end until the user says "yes" by pressing [Y].
- It uses a repeat loop, which simply repeats everything
- between the words "repeat" and "until" until the condition
- listed after "until" is true. GetAnyKey and GetYN wait for
- the user to press a key. The difference is that GetYN is
- specific, it waits for the key pressed to be 'Y' or 'N'.
- Both of these procedures assign the character of the key
- pressed to a global character variable called U. So, when
- GetAnyKey or GetYN are done, u becomes what the user pressed.
- In the special case of GetYN, if the user pressed a small
- case 'y' or 'n', it is automatically converted into a capital
- letter. Furthermore, GetYN makes u := 'Y' if the left mouse
- button was clicked, and u := 'N' if the right mouse button
- was clicked.
-
- program prog9;
- uses crt, magic;
- begin
- repeat
- sent[1] := 'Do you want to quit? (Y/N)';
- GetYN(-5,3);
- until u = 'Y';
- end.
-
- Prog10 introduces a new magic procedure called Dialog. With
- this, you can pose a question, and have the user type an
- answer. Try it.
-
- program prog10;
- uses crt, magic;
- begin
- sent[1] := 'How would you answer this question?';
- Dialog(-1,-1);
- sent[1] := 'User typed:';
- sent[2] := Answer;
- GetAnyKey(-1,-1);
- end.
-
- Prog10 allows the user to type the answer, then if your
- program were more sophisticated that prog10, you could
- process that answer. The answer is contained in the global
- string variable Answer which GetAnyKey uses to display the
- result. Notice that "User typed:" is in single quotes,
- telling GetAnyKey to type literally that, but Answer is not
- in quotes, telling it to print the string represented by the
- variable answer, and not type "Answer".
-
- In prog10, you could make the whole operation more
- evident if you used some color control. Try prog11.
-
- program prog11;
- uses crt, magic;
- begin
- sent[1] := 'How would you answer this question?';
- Dialog(-1,-1);
- BoxBack := White;
- Border := LightBlue;
- BoxText := Green;
- Shadow := Magenta;
- sent[1] := 'User typed:';
- sent[2] := Answer;
- GetAnyKey(-1,-1);
- end.
-
- Prog11 is ugly, but you can see how to change the colors
- within the text box. The colors seem to be used here as some
- sort of variables and they are. They are pre-defined
- constants from the Turbo Pascal Crt unit. The Box colors,
- Border, and Shadow are global variables from the magic unit.
- The Colors could just as easily have been represented by
- numbers, as in the following example:
-
- program prog11a;
- uses crt, magic;
- begin
- sent[1] := 'How would you answer this question?';
- Dialog(-1,-1);
- BoxBack := 15;
- Border := 9;
- BoxText := 2;
- Shadow := 5;
- sent[1] := 'User typed:';
- sent[2] := Answer;
- GetAnyKey(-1,-1);
- end.
-
- Lets find out what all the colors are: Here is a slightly
- more complex program than any we have made so far:
-
- program prog12;
- uses crt, magic;
- begin
- border := white;
- BoxBack := black;
- CenterJustify := true;
- sent[1] := 'Type a number from 0 to 15.';
- dialog(-1,-1);
- repeat
- BoxText := number;
- if (BoxText < 1) or (BoxText > 15) then boxtext := 15;
- sent[1] := 'The current color is #' + answer;
- sent[2] := 'Type a number from 0 to 15';
- sent[3] := 'or type 16 to exit';
- dialog(-1,-1);
- until answer = '16';
- end.
-
- In detail, prog12 does this: First, the Border color and the
- BoxBack color are changed. CenterJustify will center text in
- the pop up boxes.
- Then a one-line dialog box appears. As soon as the user
- answers the question in this dialog box, a repeat loop,
- starts. The repeat loop changes the BoxText color to the
- "number" corresponding to what the user typed in the dialog
- box. "Number" is a function from the magic unit. It takes
- the Answer string (as returned by Dialog) and converts it
- from a string into an integer variable. That way it can be
- assigned to BoxText and BoxText will be able to handle it.
- Since the only 'seeable' colors range from 1 to 15 (#0 is
- black), the line starting with 'if' repairs the boxtext
- number if it not suitable.
- BoxText is a byte variable (only values it can handle are
- 0 through 255), but Answer is a string. Number fixes that by
- becoming a integer compatible with BoxText.
- Within the repeat loop a new box pops up containing three
- lines of text written in the color corresponding to the
- number the user typed in the dialog box.
- This all repeats until the user types "16".
-
- Let's make that program a little cleaner:
-
- program prog13;
- uses crt, magic;
- begin
- border := white;
- BoxBack := black;
- CenterJustify := true;
- sent[1] := 'Type a number from 0 to 15.';
- dialog(-1,-1);
- repeat
- BoxText := number;
- if (BoxText < 1) or (BoxText > 15) then boxtext := 15;
- sent[1] := 'The current color is #' + answer;
- sent[2] := 'Type a number from 0 to 15';
- sent[3] := 'or type 16 to exit';
- dialog(-1,-1);
- until (answer = '16') or (u = #27);
- end.
-
- There is only one small change. Can you spot it? The
- second-from last line now allows the user out of the loop by
- typing "16" or by pressing the [Esc] key which is Ascii #27.
- This is because Dialog uses the global character u to build
- the Answer string. U always contains the character value of
- the last character entered, which in the case of pressing the
- [Esc] key would be #27.
-
- Prog14 will be our first program that does something useful
- in the real world. It will produce the square of an integer.
- I know that's not much. You paid around $1000 for your
- computer, but your $5 calculator can do squares, and it can
- even do it with floating point numbers, which this example
- can't. The importang thing is, once you learn this, you can
- build on this program.
-
- program prog14;
- uses crt, magic;
- var
- thing : word;
- begin
- repeat
- sent[1] := 'Type a number to be squared';
- sent[2] := 'or press [Esc] to end program';
- dialog(3,3);
- if u <> #27 then
- begin
- thing := number * number;
- str(thing,answer);
- sent[1] := 'The square is ' + answer;
- GetAnyKey(40,15);
- XClear;
- end;
- until (u = #27);
- end.
-
- Prog14 introduces two new concepts. First we have a line that
- contains "var." This line is found before the first begin in
- any procedure, or before the body of a program but after the
- uses clause. The lines that follow "var" are "user-declared"
- variables. If they are declared before the main body of the
- program they are "global," usable throughout the program. If
- they are declared within a function or procedure, they are
- usable only by that function or procedure.
- In this case, we have declared, "thing : word." on the
- left of the colon (notice no = sign) is any combination of
- letters and numbers and "_" allowed by Turbo Pascal (see
- manual). On the right of the colon is the type of variable it
- is. A word is a integer number with a positive value from 0
- to approximately 64000. Other common types appointed by Turbo
- Pascal are integer (approx value -32000 to +32000), real
- (floating point number), byte (0 to 255), char (Any ASCII
- character), string (an array, or group of characters),
- pointer (indicating the starting location of a variable of
- any type stored in memory) and an array (a group of any of
- these items). Additionally, you can make up your own types,
- composed of one or more of these basic types in a mixture.
- For more information about all this, watch the Var section of
- the programs that follow in this tutorial, and see your
- Borland manuals.
- Furthermore, we introduced "str" which is a Borland
- procedure to convert a numeric variable into a string
- representing that number in text.
- This program is easy to crash. All you have to do is
- pick a number that's square is more than the range of a
- "word" type variable. (64000)
- There are a couple more new things here, but if you are
- sharp, you probably already picked them out. One is the "*"
- which is computer programming talk for "multiply". The other
- is the "<>" which means "not equal to."
- This program will be quite confusing, it would have been
- confusing to me for the first year or so that I was using
- Turbo Pascal, so you might want to study it carefully. Once
- you understand what everything does, try making changes and
- see if the do what you would expect. Once you get it, you're
- well on your way to writing custom programs.
-
- Most of prog15 is similar to the last, but this one is
- for converting inches to millimeters. Try it and you'll see a
- surprise.
-
- program prog15;
- uses crt, magic;
- var
- millimeters : real;
- begin
- repeat
- sent[1] := 'Enter a number of inches';
- sent[2] := 'or press [Esc] when done';
- dialog(2,2);
- if u <> #27 then
- begin
- millimeters := number * 25.4;
- str(millimeters,answer);
- sent[1] := 'That would be ' + answer + ' millimeters';
- GetAnyKey(30,20);
- xclear;
- end;
- until u = #27;
- end.
-
- The surprise is in the way Turbo Pascal handles real
- variables when converted to string variables. Unless you add
- specific formatting commands, you'll get scientific notation.
- So, prog15a has a small change in the str procedure
- parameters, specifically, "millimeters" is followed with
- ":1:0." See your Borland books for more information, but
- basically, if the first integer is anything less than 8, then
- up to 8 digits will be displayed. The second integer
- determines how many digits after the decimal point will be
- considered in the string. For monetary notations, your second
- integer would typically be 2, for cents.
-
- program prog15a;
- uses crt, magic;
- var
- millimeters : real;
- begin
- repeat
- sent[1] := 'Enter a number of inches';
- sent[2] := 'or press [Esc] when done';
- dialog(2,2);
- if u <> #27 then
- begin
- millimeters := number * 25.4;
- str(millimeters:1:0,answer);
- sent[1] := 'That would be ' + answer
- + ' millimeters';
- GetAnyKey(30,20);
- xclear;
- end;
- until u = #27;
- end.
-
- Program 16 converts Dupers from the country Xanopieland
- to United States Dollars.
-
- program prog16;
- uses crt, magic;
- var
- dollars : real;
- begin
- centerjustify := true;
- sent[1] := 'How many Dupers?';
- dialog(-1,-1);
- dollars := number * 0.7143; {current duper
- conversion rate}
- str(dollars:1:2,answer);
- sent[3] := '$' + answer;
- sent[2] := '';
- sent[1] := 'You own this much Xanopieland money:';
-
- (* notice that sent[3] is assigned above *)
-
- sent[4] := '';
- sent[5] := 'Press any key to end program...';
- GetAnyKey(-1,-1);
- end.
-
- Prog16 introduces comments. There are two ways you can put
- comments into your source code that won't affect the way your
- program is compiled. One is to place it between curly
- brackets {} and the other way is to use (* and *) as the
- borders of comments. Comments can extend over several lines
- as long as the beginning is marked with { or (* and the end
- is marked with the matching } or *). You can even nest one
- type within another:
- {comment (* within a comment *)}
- No matter how many comments you put in your source code,
- there will be no change in the compiled program's size or run
- time speed.
- Comments can be very important for you or for others that
- have to figure out your programs a long time after you have
- created them.
- Prog16 also illustrates that Turbo Pascal is not at all
- fussy about white space. The only place white space matters
- is within strings. The same program can be written this way:
-
- program prog16a; uses crt, magic; var dollars : real; begin
- centerjustify := true; sent[1] := 'How many Dupers?';
- dialog(-1,1); dollars := number * 0.7143; {current duper}
- {conversion rate} str(dollars:1:2,answer); sent[3] := '$' +
- answer; sent[2] := ''; sent[1] :=
- 'You own this much Xanopieland money:'; (* notice that
- sent[3] is assigned above *) sent[4] := ''; sent[5] :=
- 'Press any key to end program...'; GetAnyKey(-1,1); end.
-
- Program 16a is just as easy for the compiler to read, but
- much harder for humans to read!
-
- Let's make one more improvement in prog16. In prog16b, we'll
- straighten out the way Dupers can be entered. The standard
- dialog box is as wide as the widest sent[] and therefore the
- answer can be that long. What if you want to limit the user
- to a 4-digit answer, for instance? The following technique
- works well for use with filling in database forms:
-
- program prog16b;
- uses crt, magic;
- var
- dollars : real;
- begin
- centerjustify := true;
- sent[1] := 'How many Dupers?';
- sent[2] := ' '; {must be at least one char}
- pop(-1,-1);
- textcolor(BoxText);
- textbackground(BoxBack);
- answer := XReadLn(38,12,4);
- restore;
- dollars := number * 0.7143;
- str(dollars:1:2,answer);
- sent[3] := '$' + answer;
- sent[2] := '';
- sent[1] := 'You own this much Xanopieland money:';
- sent[4] := '';
- sent[5] := 'Press any key to end program...';
- GetAnyKey(-1,-1);
- end.
-
- Can you spot the differences? This program does not depend on
- Dialog. Instead, we pop up a box with "pop," which is a
- simple procedure that remembers what's on the screen, then
- puts a box on the screen. Since pop will use only as many
- sent[]s as have text, sent[2] is ' ', or one blank, so it
- will be included in pop's box. This will give the user a
- line within the box on which to type the answer.
- Then the current text color and background color are set
- to the same as the colors within the box, so that XReadLn,
- will work in the proper colors. XReadln is like the Turbo
- Pascal ReadLn procedure but with three differences. XReadLn
- accepts mouse control (left mouse button is like pressing
- [Enter] and right button is like [Esc]), XReadLn requires two
- integers to designate the screen coordinates at which it will
- echo the text typed by the user, and a third integer which
- limits how long a string the user is allowed to type.
- Dialog knows when the user is done, and restores the
- screen and disappears, but pop doesn't know what is wanted,
- so stays on the screen until a specific call to Restore,
- which wipes it out and replaces the previous screen image.
-
- Prog17 shows many new techniques. It is the Universal Money
- Converter. For simplicity, only the first menu entry has a
- procedure installed. Run this program to see what it does,
- then study the source code to see how it does it. From a
- practical point of view, you can see that with modifications,
- this could be used for real money from real countries. For
- that matter, the same program could be modified for many
- purposes. How about a universal metric converter that
- converts lengths, weights, temperatures, etc?
- (NOTE: When I first roughed out this tutorial, I got to
- thinking about the previous sentence, and an idea was born.
- It is now complete and being distributed as shareware.
- Perhaps you've seen it, THE UNIVERSAL CONVERTER. This new
- program performs over 600 useful calculations and it makes
- extensive use of Pascal Magic!)
-
- program prog17;
- uses crt, magic;
- var
- dollars : real;
-
- procedure xano;
- begin
- sent[1] := 'How many Xanopieland Dupers?';
- sent[2] := ' '; {must be at least one char}
- pop(-1,-1);
- textcolor(BoxText);
- textbackground(BoxBack);
- answer := XReadLn(38,12,4);
- restore;
- dollars := number * 0.7143;
- str(dollars:1:2,answer);
- sent[3] := '$' + answer;
- sent[2] := '';
- sent[1] := 'You own this much Xanopieland money:';
- sent[4] := '';
- sent[5] := 'Press any key to continue...';
- GetAnyKey(-1,-1);
- end;
-
- begin {main}
- centerjustify := true;
- sent[1] := 'Universal Money Converter';
- pop(25,2);
- mc := 1;
- repeat
- sent[1] := 'Xanopieland';
- sent[2] := 'Braze Island';
- sent[3] := 'Nomania';
- sent[4] := 'Grazille';
- sent[5] := 'Exit to Dos';
- menu(-1,-1);
- if u = #13 then
- begin
- if mc = 1 then xano;
-
- (* if mc = 2 then braze;
- if mc = 3 then nomania;
- if mc = 4 then Grazille; *)
- end;
- until (u = #13) and (mc = 5);
- CleanUp;
- end.
-
- The most noticeable change is the use of a sub-routine,
- called a "procedure." And Pascal seems kind of backward at
- first - the main program is the bottom-most thing, and the
- procedure(s) are at the top. In Pascal, it must be this way.
- Any procedure or function that is called from another
- procedure or function, or from the main program, must be
- above it in the source code. Actually, there are ways around
- this (see Forward declaration in your Borland manuals), but
- for now, we'll keep it simple.
- The procedure Xano is called only when the user selects
- the first menu entry.
- Now, let's look at the main program to see exactly what it
- does. You know CenterJustify. It makes all the sent[]s
- centered within the pop-up boxes.
- Then a box pops near the top of the screen with the text,
- "Universal Money Converter." Then we have a funny line, "mc
- := 1." I'll explain that one in a minute.
- Within the repeat loop are 5 sent[]s and a call to the
- magic procedure "menu". Menu is like the other pop-up boxes
- you are familiar with, but it is a light-bar menu. It allows
- the user to highlight any one of the sent[]s by moving the
- mouse or using the arrow keys. When the user presses [Enter],
- [Esc] or a mouse button, the menu box disappears. A global
- integer variable, "mc" is assigned the number of the sent[]
- that was highlighted when the menu box disappears. So if the
- user has highlighted Nomania (sent[3]), then pressed [Enter],
- then mc will equal 3.
- And after the menu box disappears, the next line of code
- will be executed, which happens to be "if mc = 1 then xano."
- Well, if the user selected Nomania, then mc is not 1 and the
- procedure xano will not be run. mc = 3, but the line, "if mc
- = 3 then nomania" is commented out, so nothing will occur.
- However, if the user had selected Xanopieland, then mc would
- be 1 and the procedure xano would be executed. And you know
- what that does, it is the same as prog16. If the user should
- select sent[5] then mc will be 5 and the until clause will
- then allow the program to end. The last procedure in the
- program is CleanUp which restores everything to the way it
- was before the program started. It resets the screen colors,
- clears the screen and the program terminates gracefully.
- CleanUp should be used at the end of every program. It has a
- very specific purpose here. Remember the one-line pop at the
- beginning of the program? It held a picture of what's under
- that box in memory and is still holding it until calling
- CleanUp. We never "Restore"d the first "pop".
- Now about that line "mc := 1." Without this line, when
- menu is first started, it doesn't know which sent[] to
- highlight. You must tell it. If you forget to assign a value
- to mc before calling a menu, then a random item will be
- highlighted. Notice that "mc := 1" is before the repeat loop.
- This is because, once the repeat loop starts, the user may be
- most comfortable seeing the menu pop-up with the highlight
- where it was last located rather than on the top item every
- time.
-
- Prog18 is the same as the last one, except we use DoubleMenu
- instead of Menu. Everything is the same, but the menu is
- shorter and wider, allowing for situations where you may have
- lots of menu choices. You can use up to 36 sent[]s with
- DoubleMenu.
-
- program prog18;
- uses crt, magic;
- var
- dollars : real;
-
- procedure xano;
- begin
- sent[1] := 'How many Xanopieland Dupers?';
- sent[2] := ' '; {must be at least one char}
- pop(-1,-1);
- textcolor(BoxText);
- textbackground(BoxBack);
- answer := XReadLn(38,12,4);
- restore;
- dollars := number * 0.7143;
- str(dollars:1:2,answer);
- sent[3] := '$' + answer;
- sent[2] := '';
- sent[1] := 'You own this much Xanopieland money:';
- sent[4] := '';
- sent[5] := 'Press any key to continue...';
- GetAnyKey(-1,-1);
- end;
-
- begin {main}
- centerjustify := true;
- sent[1] := 'Universal Money Converter';
- pop(25,2);
- mc := 1;
- repeat
- sent[1] := 'Xanopieland';
- sent[2] := 'Braze Island';
- sent[3] := 'Nomania';
- sent[4] := 'Grazille';
- sent[5] := 'Exit to Dos';
- doublemenu(-1,-1);
- if u = #13 then case mc of
- 1 : xano;
- (* 2 : brace;
- 3 : nomania;
- 4 : grazille; *)
- end;
- until (u = #13) and (mc = 5);
- end.
-
- In prog18 we have also cleaned up the multiple if statements
- by using a "case" statement. But, there are still no
- procedures written for 3 of the 5 menu choices, so these are
- commented out.
-
- Prog19 adds another case statement allowing the user to
- press a key corresponding to the first letter of a menu item
- and then that procedure will be run directly.
-
- program prog19;
- uses crt, magic;
- var
- dollars : real;
-
- procedure xano;
- begin
- sent[1] := 'How many Xanopieland Dupers?';
- sent[2] := ' '; {must be at least one char}
- pop(-1,-1);
- textcolor(BoxText);
- textbackground(BoxBack);
- answer := XReadLn(38,12,4);
- restore;
- dollars := number * 0.7143;
- str(dollars:1:2,answer);
- sent[3] := '$' + answer;
- sent[2] := '';
- sent[1] := 'You own this much Xanopieland money:';
- sent[4] := '';
- sent[5] := 'Press any key to continue...';
- GetAnyKey(-1,-1);
- end;
-
- begin {main}
- centerjustify := true;
- sent[1] := 'Universal Money Converter';
- pop(25,2);
- mc := 1;
- repeat
- sent[1] := 'Xanopieland';
- sent[2] := 'Braze Island';
- sent[3] := 'Nomania';
- sent[4] := 'Grazille';
- sent[5] := 'Exit to Dos';
- doublemenu(-1,-1);
- if (u = #13) then case mc of
- 1 : xano;
- (* 2 : brace;
- 3 : nomania;
- 4 : grazille; *)
- end
- else
- case upcase(u) of
- 'X' : xano;
- (* 'B' : braze;
- 'N' : nomania;
- 'G' : grazille; *)
- 'E' : begin
- mc := 5;
- u := #13;
- end;
- end;
- until (u = #13) and (mc = 5);
- end.
-
- There are opportunities for bugs here. You want to make sure
- u = #13 (the [Enter] key) before allowing the first "case" to
- execute, because otherwise, a procedure may run twice in a
- row if the user presses a character key, first when mc =
- whatever, then then when u = 'whatever'. Also make sure to
- put the second case characters in single quote marks. And
- last, notice the "upcase(u)." Without this the user would
- have to press the shift key to get the desired result. Upcase
- converts u into a capital letter.
-
- Prog20 is going to be a big, but very special program because
- it will be something you'll use everyday. Run it and see
- what it does, then study the source code to understand it.
-
- program prog20;
- uses crt, magic;
-
- procedure extkey; (* 1 *)
- var
- tempstr : string[3];
- ekey : boolean;
- begin
- XClear; (* 8 *)
- sent[1] := 'Press any key to see it''s extended code';
- sent[2] := 'Press ''Q'' when done.';
- pop(18,3);
- sent[1] := ' '; (* 9 *)
- sent[2] := '';
- repeat
- ekey := false;
- GetAnyKey(-1,-1);
- if u = #0 then
- begin
- sent[1] := '#0 + ';
- u := readkey;
- ekey := true;
- end;
- case u of
- #13 : answer := ' '; (* 10 *)
- #8 : answer := ' ';
- #10 : answer := ' ';
- #7 : answer := ' ';
- else answer := u;
- end; {case}
- str(ord(u),tempstr);
- sent[1] := sent[1] + answer + ' (#' + tempstr + ')';
- until (upcase(u) = 'Q') and (ekey = false);
- XClear;
- end; {procedure ExtKey}
-
- procedure asciichart;
- var
- x,y : byte; (* 3 *)
- temp : integer;
- begin
- textcolor(white); textbackground(black);
- x := 1;
- y := 1;
- clrscr;
- for temp := 0 to 255 do
- begin
- u := chr(temp); (* 4 *)
- gotoxy(x,y); (* 5 *)
- write(' ');
- if temp < 10 then write(' ');
- if temp < 100 then write(' ');
- if (temp <> 7) and (temp <> 8) and (temp <> 10)
- and (temp <> 13) and (temp <> 27) (* 11 *)
- then write(temp,'=',u,' ')
- else write(temp,'=');
- inc(y); (* 6 *)
- if y > 25 then
- begin
- y := 1;
- x := x + 7;
- end;
- end; {end of for 0 to 255 loop}
- WaitForUser;
- xclear; (* 7 *)
- end; {procedure Asciichart}
-
- begin {main}
- centerjustify := true;
- mc := 1;
- repeat
- BoxBack := red;
- sent[1] := 'Programmer''s Tools';
- sent[2] := 'Copyright 1991, Freeware by Another Company';
- pop(18,2);
- BoxBack := green;
- sent[1] := 'ASCII Chart';
- sent[2] := 'Extended Keys';
- sent[3] := 'Quit';
- menu(-1,-1);
- if u = #13 then
- case mc of
- 1 : AsciiChart; (* 2 *)
- 2 : ExtKey;
- end;
- until (u = #13) and (mc = 3);
- CleanUp;
- end.
-
- I've tagged this file with note numbers surrounded by (* and
- *). Note 1) Don't look here to start reading a program, this
- is merely a sub-routine. Go way down to the main program
- block, where it says "{main}" to get a feel for what's going
- on.
- Looking at the overall program you'll see that there is
- the main program block and two procedures, which may be
- called from the case statement in the main block.
-
- Note 2) If the user selects the first menu item, "ASCII
- Chart" then MC will be 1, and the AsciiChart procedure will
- be called. Now let's go up and take a look at that procedure.
-
- Note 3) Here are some variables being declared within this
- procedure. They are not available to the main program. X and
- y are bytes, they can hold a value of from 0 to 255. Temp is
- an integer, with a possible value of from approx -32000 to
- +32000. If you look down a few lines, you'll see that x and y
- are specifically set to 1. In Pascal, as in most programming
- languages, the act of declaring a variable doesn't set it to
- 0 or any other value. Unless specifically set to something,
- it's value will be random. In this procedure, the values of
- x and y need to start with 1.
-
- Note 4) We are in a "for" loop which as it is set up in this
- program will start with temp defined as 0 and the contents
- of the loop (between the "begin" and "end" will repeat 255
- times, and each time, the value of temp will be increased by
- 1.
- The first thing that happens in this loop is that u, a
- global char variable, is set to the ASCII character
- represented by the value of temp. This is done by the Turbo
- Pascal function "chr."
-
- Note 5) The next thing that happens in this loop that
- repeats 255 times is "gotoxy." Gotoxy moves the cursor to the
- coordinates in the parentheses. Then, with close study,
- you'll figure out what is written to the screen by the
- program in the several following lines of code.
- Following this, are a few lines to make columns on a
- single screen rather than simply scrolling down 255 lines.
- I'll let you figure out how that's accomplished by studying
- the code.
-
- Note 6) This note calls your attention to the line,
- "inc(y)." Inc adds 1 to an integer value. It is like saying,
- "y := y + 1. By doing this, when the next iteration of the
- loop occurs, and the gotoxy is encountered, the next
- character will be written one line below the last, because
- of y being one number higher.
-
- Note 7) After the 255 executions of the for loop, the
- program calls the magic procedure WaitForUser, which waits
- for the user to press a key or click a mouse button. The
- next line is XClear, which clears the screen in preparation
- to return to the main program.
-
- Note 8) is way up high in the code, in the top procedure.
- This procedure, ExtKey is the one which pops up the ASCII and
- Extended Key information in a little window for each key that
- is pressed. First thing this procedure does is clear the
- screen again. Then it makes a box with a couple of sent[]s
- explaining, "Press any key to see it''s extended code," and
- "Press ''Q'' when done." Look at all those single quote
- marks! There are two of them after in it''s, and two single
- quote marks in a row on either side of the ''Q''. No, they're
- not typographical errors. This is how Turbo Pascal
- differentiates between the beginning and end of a literal
- string, and a string containing a ' in it. When there are two
- ''s, Pascal prints it on the screen as a single '. When there
- is just one ' in the source code, Turbo Pascal thinks you are
- trying to mark the beginning or end of a literal string.
-
- Note 9) The first time the ExtKey procedure runs, as you may
- recall, a little box containing nothing appears, until you
- press a key to fill it. Sent[1] has to be something, or the
- program will think there are no sent[]s at all, so sent[1] is
- a one-character string containing a space. sent[2] must be
- specifically rewritten as a string containing nothing,
- because the preceding pop had used two sent[]s, and the
- information in sent[]s is not cleared after a call to pop,
- as it would be in pop-up boxes that automatically disappear
- after they are done.
-
- Notes 10 and 11) Some characters, when written to the
- "screen" do funny things. #8 is the backspace character
- which will actually back up the cursor and cause something
- else to be overwritten. #13 is a carriage return and #10 is
- a line feed, which would screw up a chart or anything you try
- to display normally. #7 goes "beep!" So such characters must
- specifically eliminated if you try to write them literally
- to the screen.
-
- This is an excellent program to study in detail. A really
- good way to understand it is to modify it. Experiment. Make
- changes, and see if when you run the program, your changes
- act as you had expected. See if you can improve on this
- program or add new features. If you can understand all of
- this, you are well on your way to being a GOOD programmer.
-
- Prog21 is derived from prog20. It is a demonstration of
- writing to a disk file. The object of this program is to put
- a column of ASCII equivalents in a text file, so you can use
- it with your word processor, etc. Run prog21, then go look at
- the file called ASCII.TXT with the Turbo Pascal IDE or your
- favorite word processor. Be aware, prog21 is very slow,
- requiring several seconds to run its course.
-
- program prog21;
- uses crt,magic;
- var
- temp : integer;
- tempstr : string;
- begin
- NameOutFile('Ascii.txt');
- for temp := 0 to 255 do
- begin
- str(temp,tempstr);
- tempstr := tempstr + ' = ' + chr(temp);
- FileWriteLn(tempstr);
- end;
- end.
-
- There are two special items in the magic unit, "InFile" and
- "OutFile." InFile is used to get text in from the disk and
- use it within your program. OutFile is used to put
- information out to the disk. Essentially, these are pathways
- to disk files. You must give them names that will be used in
- the disk directory. As usual with disk files, these names
- must be DOS-legal, with up to 8 characters, optionally
- followed by a period and up to a three-character extension.
- Drive designator and sub-directory designations can precede
- file names.
-
- So we would use OutFile to convey information to the disk.
- The first operation in prog21 is to associate a disk filename
- with outfile, using "NameOutFile."
- Then a for loop creates a string, "tempstr" containing
- each ASCII number and the character represented by that
- number. The line in this loop, "FileWriteLn" writes this
- tempstr to the disk.
- There is another procedure called FileWrite which writes
- strings to disk, but does not put each one on a separate
- line. This follows the convention of Turbo Pascal's Write
- and Writeln.
- If you have named a file that does not yet exist on disk,
- it will be created automatically with the first call to
- FileWriteLn or FileWrite. If the file already exists, the
- string passed with FileWriteLn or FileWrite will be appended
- to the end of the file.
- You'll notice two things about FileWriteLn, one iis that
- it is very slow. FileWriteLn is nice, because it
- automatically does several things that you would normally
- have to write separately into your program, but that's why it
- is slow.
- The other thing you'll see when you look at the finished
- file. Some of the characters do funny things when written to
- a file, causing a sort of misalignment. These are things like
- line feed (#10) and Bell (#7), which beeps if read by the DOS
- type command.
-
- Prog22 is a variation of the previous program that handles
- writing to file more manually, resulting in a much faster
- program, and eliminates the funny characters.
-
- program prog22;
- uses crt,magic;
- var
- temp : integer;
- tempstr : string;
- outfile : text;
- begin
- assign(outfile,'Ascii.txt');
- rewrite(outfile);
- for temp := 0 to 255 do
- begin
- str(temp,tempstr);
- tempstr := tempstr + ' = ';
- if (temp <> 7) and (temp <> 10) and (temp <> 13)
- and (temp <> 26) then tempstr := tempstr + chr(temp);
- writeln(outfile,tempstr);
- end;
- close(outfile);
- end.
-
- Cleaner and faster, eh? I won't go into the specifics of
- file handling here, it is all well documented in your Turbo
- Pascal manuals. There are three types of files you can work
- with, with text files being the most often used by new
- programmers, and there are many things you can do with files
- besides simple reading and writing of strings. For that
- matter, there's a whole bunch of things you can do with
- strings, but all that is well beyond the scope of this humble
- tutorial.
-
- The compliment of FileWriteLn is FileReadLn. Prog23 shows it
- in operation, using the previously created Ascii.txt.
-
- program prog23;
- uses crt,magic;
- var
- tempstr : string;
- begin
- clrscr;
- NameInFile('Ascii.txt');
- repeat
- tempstr := FileReadLn;
- writeln(tempstr);
- until problem;
- WaitForUser;
- CleanUp;
- end.
-
- Not very elegant, since the stuff scrolls right off the
- screen, but you get the general idea. Notice the 4th line
- from the bottom: "until problem". This introduces something
- very excellent about the magic unit. It is always watching
- for mistakes. If you ask most of the functions and procedures
- in the magic unit to do something that can't be done, they do
- not crash the program. Instead, they handle the problem as
- gracefully as possible and set a global boolean variable to
- true. If there is no problem with your use of the function or
- routine problem is false.
- In this case, if you try to read beyond the end of the
- file, FileReadLn turns problem to true, and this particular
- program's repeat until loop falls through, and the program
- ends. If you forced the issue or wrote a program that does
- not regard "problem" then any subsequent attempts to use
- FileReadLn would simply assign #0 to tempstr.
- In Turbo Pascal, files that are read from or written to
- must first be opened, the operation(s) performed, then
- closed. FileWrite and FileWriteLn handle all this
- automatically, but FileRead and FileReadLn cannot, because if
- you were to make subsequent calls to these and they did open
- and close the file each time, each time you read, you would
- always get the first line in the file, since opening a file,
- resets it to the beginning.
- So from the first time you read the file with FileRead or
- FileReadLn, InFile remains open. It should be closed before
- the program ends, and the best way to do that is to call the
- very standard procedure, "CleanUp" which is specifically
- designed to be the last line in any program. It closes all
- open files, resets the video mode, clears the screen and
- frees up memory. It never hurts to have this line at the end
- of any program, and it is essential at the end of some.
- If you have read several lines in infile, then you want
- to start over at the top, do this: "reset(infile)."
-
- Prog24 explores graphics a bit. Compile it, run it, study it.
-
- program prog24;
- uses crt, video, magic;
- begin
- sent[1] := 'This is text mode';
- GetAnyKey(-1,-1);
- BestVideo;
- sent[1] := 'This is a graphics mode';
- GetAnyKey(-1,-1);
- CleanUp;
- end.
-
- As you can see, it is quite simple. There are only two new
- things in this program. Can you spot them? The first is the
- use of a new unit, "Video." The second is a procedure called
- "BestVideo." BestVideo is a procedure that figures out what
- type of monitor you have, then sets up the program to run on
- your graphics card.
- And there is a special surprise. Those of you who have
- done some graphics work in Turbo Pascal will recognize it's
- benefit right away. When you call BestVideo, it automatically
- incorporates the graphics drivers into your compiled .EXE
- file. Usually, the Borland Graphics Interface files (*.BGI)
- must be distributed on the disk along with your program.
- There are several video procedures within the magic unit.
- They are CGAVideo, HercVideo, EGAVideo, VGAVideo, BestVideo,
- and TextVideo. If you use HercVideo, in place of BestVideo,
- then the program will work only on computers equipped to
- display Hercules Graphics, but the compiled program will be
- much smaller, and you can use absolute coordinates to display
- graphics.
- BestVideo will link in all the *.BGI files and then
- automatically detect which graphics card is present in any
- computer, and therefore will run on practically any IBM-clone
- that has any graphics card. But BestVideo has to incorporate
- all the graphics drivers, and therefore the finished product
- is larger. Furthermore, when using BestVideo, you have to
- account for different resolutions on different machines. On
- a CGA machine, the coordinates 0,180 are near the bottom left
- edge of the screen, but on VGA 0,180 is on the left, but
- nearer to the top of the screen. With BestVideo, you have to
- make calculations based on GetMaxX, and GetMaxY, (see your
- Borland books) or use centered pop-up boxes.
- TextVideo is the way out of graphics. For instance, if
- you write a program that starts in graphics mode to display a
- drawing, then you want to switch back to text for faster
- handling of strings, you simply call the TextVideo procedure.
- Pop, GetYN, GetAnyKey, Dialog, Menu and DoubleMenu all
- work almost the same in any graphics mode as in text mode.
-
- program prog25;
- uses crt, video, magic;
- begin
- sent[1] := 'This is text mode';
- GetAnyKey(-1,-1);
- CGAVideo;
- sent[1] := 'This is a graphics mode';
- GetAnyKey(-1,-1);
- TextVideo;
- sent[1] := 'This is text again';
- GetAnyKey(-1,-1);
- CleanUp;
- end.
-
- Prog25 switches to CGA graphics mode, then back to text mode.
-
- Prog26 shows some of the complexity in using BestVideo.
-
- program prog26;
- uses crt, video, graph, magic;
- begin
- sent[1] := 'This is text mode';
- GetAnyKey(-1,-1);
- BestVideo;
- setcolor(yellow);
- circle(getmaxx div 2,GetMaxY div 2, GetMaxY div 4);
- sent[1] := 'This is a graphics mode';
- GetAnyKey(-1,-1);
- TextVideo;
- CleanUp;
- end.
-
- Notice the new unit. We are now using a unit that comes with
- Turbo Pascal called Graph.tpu. It allows us to make circles,
- rectangles, lines, change colors, and many other things. You
- should use Graph in all your graphics programs because those
- which don't make use of it will not be much larger than those
- that do. Borland's compiler is smart and strips unused code
- out of units as the program is compiled.
- This one switches to a graphics when a key is pressed. If
- you have a VGA system, then you'll see a yellow circle around
- a pop-up box. But, then change the "BestVideo" line to
- "CGAVideo" and you'll see that the pop-up box partially
- covers the circle, even though the circle is supposedly the
- same size. It's the pop-up that changed.
- Notice that you can change color by simply passing a
- color to SetColor.
-
- Prog27 shows a few of the many other things you can do with
- the Turbo Pascal Graph unit.
-
- program prog27;
- uses crt, video, graph, magic;
- begin
- BestVideo;
- SetColor(white);
- circle(100,100,50);
- circle(100,100,40);
- SetFillStyle(solidfill,white);
- FloodFill(51,100,white);
- SetColor(lightgreen);
- SetLineStyle(0,0,3);
- rectangle(70,70,130,130);
- SetFillStyle(solidfill,lightmagenta);
- bar(90,90,110,110);
- WaitForUser;
- CleanUp;
- end.
-
- Prog28 shows how to work with text in a graphics mode. Turbo
- Pascal supplies a default font, which is an 8 x 8 pixel
- bitmapped font. It is called DefaultFont.
-
- program prog28;
- uses crt, video, graph, magic;
- begin
- BestVideo;
- OutTextXY(10,100,'This is the Default font');
- WaitForUser;
- CleanUp;
- end.
-
- In Prog28 we see that the way to display a string is through
- OutTextXY, which is similar to GoToXY combined with Write in
- text mode. OutTextXY requires screen coordinates, then a
- string. Unlike write and writeln, you must pass only a
- string and only one string at a time. You must "str" numbers
- before using OutTextXY.
-
- Prog29 shows how to work with different fonts.
-
- program prog29;
- uses crt, video, graph, magic;
- begin
- BestVideo;
- Triplex;
- SetTextStyle(TriplexFont,HorizDir,4);
- OutTextXY(0,0,'This is the Triplex font');
- WaitForUser;
- CleanUp;
- end.
-
- First, you'll see a call to "Triplex." This will cause the
- external Triplex.Chr file to be compiled directly into the
- .EXE file. You do not have to distribute finished programs
- with external *.chr files! But by itself, Triplex has no
- other effect on the program. If you want to actually use the
- Triplex font, you have to use "SetTextStyle". SetTextStyle
- takes three parameters. First is an integer for the font to
- use, and these integers also have pre-declared constants in
- the graph unit. Triplex can be referred to as "1" or
- TriplexFont. The second number or constant is the
- orientation of the text. HorizDir is the most common, of
- course. It can also be represented with a 0. And finally the
- size of the font can be controlled with another integer value
- from 1 to 10.
- As tempting as it may seem, there are two reasons not to
- use any fonts except DefaultFont with Pop, GetYN, GetAnyKey,
- Dialog, Menu or Doublemenu. Gothic, Triplex, SansSerif and
- Small fonts are drawn rather than bitmapped and therefore
- take longer to generate on the screen, slowing the program
- perceptably. Furthermore, because of the way they are
- generated, they don't line up right relative to the general x
- and y coordinates used by these procedures.
-
- If you run prog29 in CGA mode (you can change BestVideo to
- CGAVideo to see) you'll notice that the line, "This is
- Triplex font." is too long to fit on the screen. So, in
- prog30, lets switch to a different CGA graphics mode.
-
- program prog30;
- uses crt, video, graph, magic;
- begin
- CGAVideo;
- SetGraphMode(4);
- Triplex;
- SettextStyle(TriplexFont,HorizDir,4);
- outtextxy(0,0,'This is the Triplex font');
- WaitForUser;
- CleanUp;
- end.
-
- The line, "SetGraphMode(4)" changes to the higher resolution,
- 2 color, 640 x 200 CGA mode.
-
- Prog31 shows off some basic mouse work, and the main
- principal of drawing to the screen.
-
- program prog31;
- uses crt, video, graph, magic;
- var
- x,y : word; {"word" is a positive integer value}
- begin
- BestVideo;
- WasteMouse;
- repeat
- poll(x,y,left,right);
- LineTo(x,y);
- until left;
- CleanUp;
- end.
-
- In prog31 a loop repeats until left becomes true. Left is a
- global boolean variable that is set to true when the user
- clicks the left mouse button. Poll is a function that asks
- the mouse to report it's current status. It tells you through
- poll, the current screen position, in this case using x and y
- as word type variables for coordinates, and the status of the
- left and right mouse buttons. Every time the mouse is polled,
- a line is drawn from where the last line ended, to where the
- mouse is currently.
- Notice the line, "WasteMouse." This is a procedure which
- stalls the program until both "left" and "right" are false.
- (no mouse buttons pressed). Without "WasteMouse" the program
- might end immediately.
-
- Prog32 shows you one way to move a rectangle around. This
- program will display the mouse pointer until the left mouse
- button is clicked, then it will turn it off and show a
- movable rectangle until the right mouse button is clicked.
-
- program prog32;
- uses crt, video, graph, magic;
- var
- x,y : word;
- begin
- BestVideo;
- WasteMouse;
- PointerToXY(GetMaxX div 2,GetMaxY div 2);
- PointerOn;
- repeat Poll(x,y,left,right) until left;
- PointerOff;
- SetWriteMode(XOrPut);
- rectangle(x,y, x + 40, y + 20);
- repeat
- rectangle(x,y, x + 40, y + 20);
- Poll(x,y,left,right);
- rectangle(x,y, x + 40, y + 20);
- until right;
- CleanUp;
- end.
-
- Prog32 shows you how to turn the mouse pointer on and off,
- and shows "SetWriteMode" so that you can eliminate images
- which have been created, by merely writing them over
- themselves.
-
- Prog33 shows a couple of small improvements:
-
- program prog33;
- uses crt, video, graph, magic;
- var
- x,y,oldx,oldy : word;
- begin
- BestVideo;
- WasteMouse;
- SetTextJustify(CenterText,BottomText);
- OutTextXY(GetMaxX div 2,GetMaxY - 4,
- 'Click right mouse button to end program');
- SetWriteMode(XOrPut);
- rectangle(x,y, x + 40, y + 20);
- repeat
- repeat
- Poll(x,y,left,right);
- until (x <> oldx) or (y <> oldy) or right;
- rectangle(oldx,oldy, oldx + 40, oldy + 20);
- oldx := x;
- oldy := y;
- rectangle(x,y, x + 40, y + 20);
- until right;
- CleanUp;
- end.
-
- First, we took off the mouse pointer stuff to simplify the
- program. Then we use one of the fancy features of the Turbo
- Pascal Graph unit to cause text to be centered from left to
- right around the x coordinate and the bottom of the string
- will be on the y coordinate. And a notice is posted for the
- user.
- Then using the new variables, "oldx" and "oldy" within the
- repeat loop, we check to see if there have been any changes
- in position before moving the rectangle. This eliminates
- annoying flashing.
-
- In our last program I'll show you how to use the sound
- effects in the magic unit, and we'll fool around with text in
- graphics modes a bit more.
-
- program prog34;
- uses crt, video, graph, magic;
- var
- x,y,oldx,oldy : word;
- begin
- SoundUp; (* 1 *)
- MainBack := black; (* 2 *)
- BestVideo;
- Gothic; (* 3 *)
- Triplex;
- SetColor(LightMagenta);
- SetTextJustify(CenterText,TopText); (* 4 *)
- SetTextStyle(GothicFont,HorizDir,6);
- OutTextXy(GetMaxX div 2,0,'Type Anything');
- SetTextStyle(TriplexFont,VertDir,1);
- SetTextJustify(LeftText,CenterText);
- OutTextXY(20,(GetMaxY div 2) + 30,'Press [Enter]');
- OutTextXY(40,(GetMaxY div 2) + 30,'when done.');
- SetTextStyle(DefaultFont,HorizDir,2);
- SetTextJustify(LeftText,TopText);
- SetFillStyle(SolidFill,black); (* 5 *)
- SetColor(LightCyan);
- Waste; (* 6 *)
- answer := '';
- repeat
- u := ReadKey;
- pink; (* 7 *)
- if ord(u) > 31 then answer := answer + u; (* 8 *)
- if u = #8 then (* 9 *)
- begin
- bar(70,100,70 + TextWidth(answer), (* 10 *)
- 100 + TextHeight(answer));
- delete(answer,length(answer),1); (* 11 *)
- end;
- OutTextXY(70,100,answer);
- until u = #13;
- SoundDown;
- delay(500); (* 12 *)
- Twinkle;
- CleanUp;
- end.
-
- Prog34 has notes within (* and *):
-
- Note 1) One of the four sound effects built into the magic
- unit. To use one of the effects, simply call it's procedure.
- Sometimes sounds don't behave as expected with machines
- faster than 33mhz or when heavily multitasked (running
- concurrently with other programs) under MS-Windows or
- Deskview.
-
- Note 2) By setting the main background color to black before
- a call to BestVideo, the video mode will start and run with a
- black background.
-
- Note 3) These procedures, Gothic and Triplex hook in the two
- fonts besides the default font that this program is going to
- use. There will be no need for *.chr files on the disk with a
- compiled program.
-
- Note 4) SetTextJustify will center a title on the screen when
- set this way.
-
- Note 5) SetFillStyle is used to establish parameters for
- "bar," used a few lines down in this program. Bar will make
- a solid rectangle in the color specified (black in this case)
- This is a good way to erase text in graphics modes.
-
- Note 6) Waste stalls the program until no mouse buttons are
- pressed and no characters have been entered from the
- keyboard. If a key had been pressed as this program was
- starting, it would be reflected as the first character in a
- string the user is going to type.
-
- Note 7) "Pink" is a sound effect, typically used to indicate
- a small action has occurred, such as a key has been pressed.
-
- Note 8) "Ord" returns the ordinal position in a set of the
- variable specified in parentheses. When used with ASCII
- characters, Ord returns their ASCII number. What this line
- does is eliminates adding characters to the string called
- "answer" if they might be unprintable characters.
-
- Note 9) u is ASCII #8 when the backspace key has been
- pressed.
-
- Note 10) "Bar" is being used to erase "answer" from the
- screen because the backspace key has been pressed and
- therefore the user wants to eliminate the last character in
- answer. The Bar will erase it, and a newer version of
- answer, one which will be one character shorter will be
- written in its place. TextWidth and TextHeight are excellent
- functions provided by Turbo Pascal to determine how many
- pixels wide and how many pixels high a string are, no matter
- what font and size are selected.
-
- Note 11) "Delete" is a way to shorten a string. Delete
- requires three parameters, the string on which to operate,
- the character position in the string at which to delete, and
- the number of characters to take out. There are several other
- string procedures available from Turbo Pascal including Pos
- (find the position of a matching sub-string within a string),
- Copy (make a sub-string from a string), and ConCat (add two
- strings together). See your Borland Turbo Pascal manuals for
- more information about string handling.
-
- Note 12) Delay is called between two sound effects to put
- some time between them. Delay requires one number, an integer
- representing the number of milliseconds to delay. There are
- 1000 milliseconds in one second, so this delay is 1/2 second.
- While Delay is running, no other actions can take place.
-
- - - -
-
- And that almost wraps up this tutorial! Hope you have had
- as much fun reading and experimenting as I did writing it.
- There is far more available in Turbo Pascal than this
- short tutorial can tell you about. To learn as much as you
- can, in a reasonable amount of time, I recommend getting
- several books on Turbo Pascal, and experimenting with every
- idea that crosses your mind.
- In fact, there's quite a bit more to the Magic unit
- itself. You can read Magic.Doc to learn more of its
- included procedures and functions, and get more technical
- information on the ones you already know.
- This is shareware. Feel free to copy and distribute Pascal
- Magic as long as all files remain intact and unchanged.
- If you have paid a professional shareware distributor a
- few dollars for this disk, you have paid for the service of
- providing a copy.
- If you use MAGIC.TPU in your programs, or if you have
- found this tutorial helpful, you must pay for the creation of
- the product. Send $29.95 to:
-
- Another Company
- P.O. Box 298
- Applegate, OR 97530
-
- Complete source code is available for the MAGIC.TPU. This
- is good for using as a framework for your own very customized
- applications, for learning more about Turbo Pascal
- Programming, for stripping down top efficiency, and for
- improving, since you will probably soon become (or might
- already be) a better programmer than I am. For registration
- AND source code, send $59.90 and please specify disk size.
-
- This is version 1.0 and you may find a bug or two. I make no
- guarantees about it's suitability to your programming needs.
-
- If we find any major bugs, they will probably be corrected
- by the time you get your registered version!
-
- If you require technical assistance, you can try to phone me
- at 503-846-7884. Best bet is 9-5 weekdays, but I'm not always
- available.
-
- Since you are going to write some wonderful programs, you
- might as well start making money with them! You won't have to
- work in an office doing programming for someone else. You
- can write exactly the kind of programs you want to write, and
- make money at home!
- The 'secret' is shareware. Does it work? You bet! You
- can easily have a small success, making some extra spending
- money each month, or with some practice, you can have a wild
- success, and make a fine living! There are some millionaires
- who make their ever-growing fortune entirely through
- shareware.
- ANOTHER COMPANY shows you everything. Besides our own
- shareware successes, including WRITER'S DREAM, BICYCLE
- TUNE-UP AND REPAIR, MONEY, BLACKBOARD, BETTER EYESIGHT,
- WHAT'S IN THAT BOX? and THE UNIVERSAL CONVERTER, we have
- researched the shareware market, we have interviewed other
- shareware authors and have learned about all sides of the
- rapidly expanding shareware business.
- We show you how to write programs that capture the
- public's interest, how to make sure your customers
- 'register', and how to get money by other means through your
- shareware. We show you more. We show you frequency charts
- indicating which types of programs sell best, we offer
- suggestions for programs as yet unwritten, we talk about
- your on-disk instruction manuals, we even show you how to
- write user-friendliness into your programs.
- Can you succeed without SUCCESS WITH SHAREWARE? Yes!
- But why do it the hard way? We have learned all the
- super-professional approaches, the pitfalls and the
- shortcuts. We'll tell you all about it, and then instead of
- stumbling around for the first couple of years, you'll be
- a professional from the start!
- To get your copy of SUCCESS WITH SHAREWARE! (which is not
- shareware, itself - only available from Another Company),
- send $19.95. Please specify if you need 3.5" disk size.
-
- Thanks,
- - Jeff Napier -
- January 9, 1992
-
- You can order products by writing your order on plain paper,
- or by printing the included ASCII file called Order.frm, or
- by phoning 1-503-846-7884, generally weekdays between 9 and
- 5, west coast time.
-